/* BresenLine.c */
/* Linienziehung im Konsole-Fenster. A. Christidis */
#include "BresenLine.h"

/*Globale Variablen: */
int  xL[]={0,0}, yL[]={0,0}, xOffset=CON_XMAX/2, yOffset=CON_YMAX/2, 
     CurPnt=1, quad=0, axes=1;
char symboL=WHITE; 

/*************************************************************************/
  void draw (void)
/*************************************************************************/
/*Standard-Struktur eines Grafik-Programms:*/
{ conClrBuff();      //Speicher loeschen

  /*Achsenkreuz:*/
  if (axes)
  { MidpointLine (0, yOffset, CON_XMAX, yOffset, '-'); 
    MidpointLine (xOffset, 0, xOffset, CON_YMAX, '|');
    conSetPixel (CON_XMAX, yOffset, '>');
    conSetPixel (xOffset, CON_YMAX, '^');
    conSetPixel (xOffset, yOffset, '+');
  }
  /*Grafik im Hintergrund aktualisieren+ausgeben:*/
  MidpointLine (xL[0]+xOffset, yL[0]+yOffset, 
                xL[1]+xOffset, yL[1]+yOffset, symboL);

  /*Bresenham setzt keinen Endpunkt - hier nachgeholt:*/
  conSetPixel (xL[1]+xOffset, yL[1]+yOffset, symboL);
  conSwapBuff();     //Hintergrund-Puffer sichtbar machen

  printf ("\r[%d,%d]---[%d,%d] \t <<type 'h' for help>>\r", 
         xL[0], yL[0], xL[1], yL[1]);
  return;
}

#define  BRESENLINE_WITH_MAIN
#ifdef   BRESENLINE_WITH_MAIN
/*************************************************************************/
  void conInit(void)
/*************************************************************************/
/*Erst- & einmalige Programm-Initialisierung:*/
{ system (CON_SIZE); // Fenster "auf Groesse" bringen
  conClrBuff();      // Speicher mit Leerzeichen "loeschen"
  conClrScr();       // Konsole-Fenster loeschen
  return;
}

/*************************************************************************/
  void key (char k)
/*************************************************************************/
/*Menue und Eingabe-Behandlung:*/
{ switch (k)
  { case CR : CurPnt = 1-CurPnt; 
              break;
    case ESC: if (!xL[0] && !xL[1] && !yL[0] && !yL[1]) exit(0);
              else {xL[0]=0; xL[1]=0; yL[0]=0; yL[1]=0; CurPnt=1;}
              break;
    case '+': axes = 1-axes;
              break;
    case '0': CurPnt=1; quad=0; xL[0]=0; xL[1]=0; yL[0]=0; yL[1]=0; 
              xOffset=CON_XMAX/2; yOffset=CON_YMAX/2;
              break;
    case '1': CurPnt=1; quad=1; xL[0]=0; xL[1]=0; yL[0]=0; yL[1]=0; 
              xOffset=0; yOffset=0;
              break;
    case '2': CurPnt=1; quad=2; xL[0]=0; xL[1]=0; yL[0]=0; yL[1]=0; 
              xOffset=CON_XMAX; yOffset=0;
              break;
    case '3': CurPnt=1; quad=3; xL[0]=0; xL[1]=0; yL[0]=0; yL[1]=0; 
              xOffset=CON_XMAX; yOffset=CON_YMAX;
              break;
    case '4': CurPnt=1; quad=4; xL[0]=0; xL[1]=0; yL[0]=0; yL[1]=0; 
              xOffset=0; yOffset=CON_YMAX;
              break;
    case 'a': if (xL[CurPnt] > -xOffset)  xL[CurPnt]--;  break;
    case 'd': if (xL[CurPnt] < CON_XMAX-xOffset) xL[CurPnt]++;
              break;
    case 's': if (yL[CurPnt] > -yOffset)  yL[CurPnt]--;  break;
    case 'w': if (yL[CurPnt] < CON_YMAX-yOffset) yL[CurPnt]++;
              break;
  }
  if (k == 'h')
  { conClrScr(); 
    printf ("\n\r Press:");
    printf ("\n\n\r <ESC>  to purge / quit");
    printf ("\n\n\r <CR>      toggle start"); if (!CurPnt) printf ("(ON)");
    printf ("/end"); if (CurPnt) printf ("(ON)"); printf (" point of line"); 

    printf ("\n\n\r +         toggle show"); if (axes) printf ("(ON)");
    printf ("/hide"); if (!axes) printf ("(ON)"); printf (" coord. axes"); 

    printf ("\n\n\r 0/1/2/3/4 choose quadrant/s (curr.: %d)", quad);
    printf ("\n\n\r a / d     decrease/increase point x-coord.");
    printf ("\n\n\r s / w     decrease/increase point y-coord.");
    printf ("\n\n\r h         Help (this menu)");
    printf ("\n\n\r Current end points: [%d,%d]---[%d,%d]", xL[0], yL[0], xL[1], yL[1]);
    printf ("\n\n\r(press any key to continue)"); 
    _getch(); draw();
  }
  return;
}

/*************************************************************************/
  int main()
/*************************************************************************/
{ int keypress=' ';
  system (CON_SIZE);
  printf ("\n\n\r  Aris Christidis: \
           \n\n\r  Bresenham Line Drawing Algorithm\
           \n\r        (incl. last point)\
           \n\n\r  [ help: <h>, quit: <ESC> ]\
           \n\n\r  (press any key)"); _getch();
  conInit();
  while (keypress)
  { draw();
    keypress = _getch();
    key ((char)keypress);
  }
  return 0;
}
#endif //BRESENLINE_WITH_MAIN
